package com.cai.service.impl;

import com.cai.enumerator.OrderStatusChangeEventEnum;
import com.cai.enumerator.OrderStatusEnum;
import com.cai.pojo.BO.Order;
import com.cai.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

/**
 * @Author czq
 * @Package com.cai.service.impl
 * @Date 2024/5/20 13:14
 * @description:
 */
@Service
@Slf4j
public class OrderImpl implements OrderService {
    @Resource
    private StateMachine<OrderStatusChangeEventEnum, OrderStatusChangeEventEnum> stateMachine;

    private  Long ORDER_ID = 1L;

    private final Map<Long, Order> orders = new TreeMap<>();

    @Override
    public Order create() {
        Order order = new Order();
        order.setOrderStatus(OrderStatusEnum.WAIT_PAYMENT);
        order.setOrderId(ORDER_ID++);
        orders.put(order.getOrderId(), order);
        log.info("订单创建成功：{}", order);
        return order;
    }

    @Override
    public Order pay(Long id) {
        Order order = orders.get(id);
        order.setOrderStatus(OrderStatusEnum.WAIT_DELIVER);
        log.info("尝试支付，订单号：{}", id);
        Message<OrderStatusChangeEventEnum> message = MessageBuilder.withPayload(OrderStatusChangeEventEnum.PAYED).setHeader("order", order).build();
        if (!sendEvent(message)) {
            log.error("支付失败，状态异常，订单号：{}", id);
        }
        return orders.get(ORDER_ID);
    }

    @Override
    public Order deliver(long id) {
        Order order = orders.get(id);
        order.setOrderStatus(OrderStatusEnum.WAIT_RECEIVED);
        log.info("尝试发货，订单号：{}", id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEventEnum.DELIVERY).setHeader("order", order).build())) {
            log.info("发货失败，状态异常，订单号：{}", id);
        }
        return orders.get(id);
    }

    @Override
    public Order receive(long id) {
        Order order = orders.get(id);
        order.setOrderStatus(OrderStatusEnum.FINISH);
        log.info("尝试收获，订单号：{}", id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEventEnum.RECEIVED).setHeader("order", order).build())) {
            log.info("收货失败，状态异常，订单号：{}", id);
        }
        return orders.get(id);
    }

    @Override
    public Map<Long, Order> getOrders() {
        return orders;
    }


    private synchronized boolean sendEvent(Message<OrderStatusChangeEventEnum> message) {
        boolean result = false;
        try {
            stateMachine.start();
            result = stateMachine.sendEvent(message);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (Objects.nonNull(message)) {
                Order order = (Order) message.getHeaders().get("order");
                if (Objects.nonNull(order) && Objects.equals(order.getOrderStatus(), OrderStatusEnum.FINISH)) {
                    stateMachine.stop();
                }
            }
        }
        return result;
    }
}
